package com.spring.sd;

import com.spring.sd.bean.Bean1;
import com.spring.sd.bean.Bean2;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;

import java.util.Arrays;

/**
 * 1、较为经典的容器，基于 classpath 下的 xml 格式的配置文件来创建 <br/>
 * 2、与 ClassPathXmlApplicationContext 相比，FileSystemXmlApplicationContext 是基于磁盘路径下 xml 格式的配置文件来创建。<br/>
 * 3、AnnotationConfigApplicationContext 基于 Java 配置类来创建。首先定义配置类：
 */
public class ApplicationContextImpl {

    public static void main(String[] args) {

        /**
         * ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext 都依赖于从 XML 文件中读取 Bean 的信息，
         * 而这都利用了 XmlBeanDefinitionReader 进行读取。
         */
        // 1、ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean-demos.xml");
        // 2、FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("F:\\code\\spring-sd\\src\\main\\resources\\bean-demos.xml");
        // 3、AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

        // 与前面两种基于 XML 创建 ApplicationContext 的方式相比，使用 AnnotationConfigApplicationContext 后，使得容器中多了一些后置处理器相关的 Bean。
        // 如果要在先前的两种方式中也添加上这些 Bean，可以在 XML 进行配置
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        Arrays.stream(context.getBeanDefinitionNames()).forEach(System.out::println);
        System.out.println(context.getBean(Bean2.class).getBean1());

    }


    /**
     * 读取xml
     */
    private static void testXmlBeanDefinitionReader() {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        System.out.println("读取之前...");
        Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach(System.out::println);
        System.out.println("读取之后...");
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions(new ClassPathResource("bean-demos.xml"));
        //reader.loadBeanDefinitions(new FileSystemResource("F:\\code\\spring-sd\\src\\main\\resources\\bean-demos.xml"));
        Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach(System.out::println);
    }


    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2(Bean1 bean1) {
            Bean2 bean2 = new Bean2();
            bean2.setBean1(bean1);
            return bean2;
        }
    }

}
